﻿using LJ.EventBus.FastDog.Data;
using Microsoft.Extensions.Logging;

namespace LJ.EventBus.FastDog.Transport.InMemoryQueue.Internal;

public class MemoryQueue(ILogger<MemoryQueue> logger)
{
    private static readonly object Lock = new();

    public Dictionary<string, List<string>> TopicGroups = [];
    public Dictionary<string, InMemoryQueueConsumerClient> ConsumerClients = [];

    public void RegisterConsumerClient(string groupId, InMemoryQueueConsumerClient consumerClient)
    {
        lock (Lock)
        {
            ConsumerClients[groupId] = consumerClient;
        }
    }

    public void Subscribe(string groupId, IEnumerable<string> topics)
    {
        lock (Lock)
        {
            foreach (var topic in topics)
            {
                if (TopicGroups.TryGetValue(topic, out var value))
                {
                    if (!value.Contains(groupId))
                    {
                        value.Add(groupId);
                    }
                }
                else
                {
                    TopicGroups.Add(topic, [groupId]);
                }
            }
        }
    }

    public void Unsubscribe(string groupId)
    {
        ConsumerClients.Remove(groupId);
        logger.LogInformation("Removed consumer client from InMemoryQueue! --> Group:{groupId}" ,groupId);

    }

    public void Send(TransportMessage message)
    {
        var name = message.GetName();
        lock (Lock)
        {
            if (TopicGroups.TryGetValue(name, out var groupList))
            {
                foreach (var groupId in groupList)
                {
                    if (ConsumerClients.TryGetValue(groupId, out var consumerClient))
                    {
                        var messageCopy =
                            new TransportMessage(message.Headers.ToDictionary(o => o.Key, o => o.Value),
                                message.Body)
                            {
                                Headers =
                                {
                                   [MessageHeaders.Group] = groupId
                                }
                            };

                        consumerClient.AddSubscribeMessage(messageCopy);
                    }
                }
            }
            else
            {
                throw new InvalidOperationException(
                    $"Cannot find the corresponding group for {name}. Have you subscribed?");
            }
        }
    }
}